﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "customwidgets.h"
#include "mycanvas.h"

#include <QLineEdit>
#include <QPropertyAnimation>
#include <QFileDialog>
#include <QDebug>

const int cornerRadius = 20;

MainWindow::MainWindow(QWidget *parent) :
    QWidget(parent)
    , ui(new Ui::MainWindow)
    , m_pTitleWidget(nullptr)
    , m_pHomePage(nullptr)
    , m_pCurCanvas(nullptr)
{
    ui->setupUi(this);

    // 强制刷新窗口
    //QCoreApplication::processEvents();

    init();
    initUi();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::resizeEvent(QResizeEvent *event)
{
    emit signalSizeChanged(size());
    QWidget::resizeEvent(event);
}

void MainWindow::init()
{
    settingPageInit();
    layoutPageInit();
    aboutPageInit();
    newPageInit();
}

void MainWindow::selectCanvas(MyCanvas *canvas)
{
    //如果当前画布为空，删除首页，展示新画布
    if(!m_pCurCanvas){
        ui->displayLayout->removeWidget(m_pHomePage);
        m_pHomePage->hide();
        ui->displayLayout->addWidget(canvas);
        canvas->show();
    }
    else{
        //否则删除旧画布，展示新画布
        ui->displayLayout->removeWidget(m_pCurCanvas);
        m_pCurCanvas->hide();
        ui->displayLayout->addWidget(canvas);
        canvas->show();
    }
    m_pCurCanvas = canvas;
    canvas->settingPage()->setParent(this);
    //当前设置页面改为该画布的设置页面
    m_pCurSettingsPage = canvas->settingPage();

    //该为当前画布的标题和描述
    m_pCanvasTitle->setText(m_pCurCanvas->name());
    m_pCanvasTitle->setMaximumWidth(QFontMetrics(QFont("Corbel Light", 24)).size(Qt::TextSingleLine, m_pCanvasTitle->text()).width() + 10);
    m_pCanvasDesc->setText(m_pCurCanvas->description());
}

void MainWindow::deleteCanvas(MyCanvas *canvas){
//    int index = canvasList.indexOf(canvas);
//    if(index < 0)
//        return;
//    canvasList.erase(canvasList.begin() + index);
//    ui->displayLayout->removeWidget(curCanvas);
//    curCanvas->hide();
//    if(canvasList.size() > 0){
//        selectCanvas(canvasList[0]);
//    }
//    else{
//        ui->displayLayout->addWidget(m_pHomePage);
//        m_pHomePage->show();
//        curCanvas = nullptr;
//        canvasTitle->setText("START");
//        canvasTitle->setMaximumWidth(QFontMetrics(QFont("Corbel Light", 24)).size(Qt::TextSingleLine, "START").width() + 10);
//        canvasDesc->setText("Add your first canvas to start");
//        curSettingsPage = defaultSettingsPage;
//    }
//    pageList.erase(pageList.begin() + pageList.indexOf(canvas->settingPage()));
//    delete canvas;
//    ui->mainWidget->update();
}

void MainWindow::settingPageInit()
{
    m_pDefaultSettingPage = new SlidePage(cornerRadius, "SETTING", this);
    //设置页为默认页
    m_pCurSettingsPage = m_pDefaultSettingPage;
}

void MainWindow::layoutPageInit()
{
    m_pLayersPage = new SlidePage(cornerRadius, "LAYERS", this);
    //m_pLayersPage->stackUnder(createNewPage);
    layerSel = new singleSelectGroup("Layers", m_pLayersPage);
    connect(layerSel, &singleSelectGroup::itemChange, m_pLayersPage, [=](){m_pLayersPage->UpdateContents();});
    textButton *openFileBtn = new textButton("Open file", m_pLayersPage);
    connect(openFileBtn, &textButton::clicked, this, [=](){
        QString inputPath = QFileDialog::getOpenFileName(this, tr("Open map"), " ",  tr("Map File(*.map)"));
        if(!inputPath.isEmpty()){
            MyCanvas *newCanvas = loadCanvas(inputPath);
            if(newCanvas != nullptr){
                canvasList.push_back(newCanvas);
                selectionItem *newLayer = new selectionItem(newCanvas->name(), newCanvas->description(), m_pLayersPage);
                layerSel->AddItem(newLayer);
                layerSel->SetSelection(newLayer);
//                pageList.push_back(newCanvas->settingPage());
                connect(newLayer, &selectionItem::selected, this, [=](){selectCanvas(newCanvas);});
                selectCanvas(newCanvas);
                connect(newCanvas, &MyCanvas::nameChanged, this, [=](QString text){
                    m_pCanvasTitle->setText(text);
                    m_pCanvasTitle->setMaximumWidth(QFontMetrics(QFont("Corbel Light", 24)).size(Qt::TextSingleLine, m_pCanvasTitle->text()).width() + 10);
                    newLayer->setTitle(text);
                });
                connect(newCanvas, &MyCanvas::descChanged, this, [=](QString text){this->m_pCanvasDesc->setText(text);newLayer->setDescription(text);});
                connect(newCanvas, &MyCanvas::setDel, this, [=](MyCanvas *c){m_pCurSettingsPage->slideOut();deleteCanvas(c);layerSel->RemoveItem(newLayer);});
                m_pCreateNewPage->slideOut();
                m_pLayersPage->slideOut();
            }
        }
    });
    textButton *addNewBtn = new textButton("Create new", m_pLayersPage);
    connect(addNewBtn, &textButton::clicked, this, [=](){rename->setValue("Layer_" + QString::asprintf("%d", canvasList.size()));redescribe->setValue("No description");m_pCreateNewPage->slideIn();});
    m_pLayersPage->AddContent(addNewBtn);
    m_pLayersPage->AddContent(openFileBtn);
    m_pLayersPage->AddContent(layerSel);
//    m_pLayersPage->show();
//    m_pLayersPage->slideIn();
}

void MainWindow::aboutPageInit()
{
    m_pSlideAbout = new SlidePage(cornerRadius, "ABOUT", this);
    textInputItem *version = new textInputItem("version", m_pSlideAbout);
    version->setValue("1.3-beta");
    version->setEnabled(false);
    textInputItem *updateDate = new textInputItem("last-upd", m_pSlideAbout);
    updateDate->setValue("2021/12/6 10:14");
    updateDate->setEnabled(false);
    textInputItem *Author = new textInputItem("author", m_pSlideAbout);
    Author->setValue("Linloir | Made with love");
    Author->setEnabled(false);
    textInputItem *lic = new textInputItem("lic", m_pSlideAbout);
    lic->setValue("MIT License");
    lic->setEnabled(false);
    textInputItem *GitHub = new textInputItem("git", m_pSlideAbout);
    GitHub->setValue("github.com/Linloir");
    GitHub->setEnabled(false);
    m_pSlideAbout->AddContent(GitHub);
    m_pSlideAbout->AddContent(lic);
    m_pSlideAbout->AddContent(Author);
    m_pSlideAbout->AddContent(updateDate);
    m_pSlideAbout->AddContent(version);
//    m_pSlideAbout->show();
//    m_pSlideAbout->slideIn();
}

void MainWindow::newPageInit()
{
    m_pCreateNewPage = new SlidePage(cornerRadius, "CREATE CANVAS", this);
    rename = new textInputItem("Name:",m_pCreateNewPage);
    rename->setValue("Layer_" + QString::asprintf("%d", canvasList.size()));

    redescribe = new textInputItem("Detail:",m_pCreateNewPage);
    redescribe->setValue("No description");

    QWidget *whiteSpace = new QWidget(m_pCreateNewPage);
    whiteSpace->setFixedHeight(30);
    singleSelectGroup *structureSel = new singleSelectGroup("Structure",m_pCreateNewPage);
    selectionItem *item_1 = new selectionItem("AL", "Use adjacent list for canvas", m_pCreateNewPage);
    selectionItem *item_2 = new selectionItem("AML", "Use multiple adjacent list for canvas", m_pCreateNewPage);
    structureSel->AddItem(item_1);
    structureSel->AddItem(item_2);
    singleSelectGroup *dirSel = new singleSelectGroup("Mode", m_pCreateNewPage);
    selectionItem *item_3 = new selectionItem("DG", "Directed graph", m_pCreateNewPage);
    selectionItem *item_4 = new selectionItem("UDG", "Undirected graph", m_pCreateNewPage);
    dirSel->AddItem(item_3);
    dirSel->AddItem(item_4);

    submit = new textButton("Create!", m_pCreateNewPage);
    connect(submit, &textButton::clicked, this, [=](){
        MyCanvas *newCanvas = new MyCanvas(cornerRadius,
                                           rename->value(),
                                           redescribe->value(),
                                           structureSel->value() == 0 ? MyCanvas::AL : MyCanvas::AML,
                                           dirSel->value() == 0 ? MyCanvas::DG : MyCanvas::UDG, this);
        canvasList.push_back(newCanvas);
        selectionItem *newLayer = new selectionItem(newCanvas->name(), newCanvas->description(), m_pLayersPage);
        layerSel->AddItem(newLayer);
        layerSel->SetSelection(newLayer);
//        pageList.push_back(newCanvas->settingPage());
        connect(newLayer, &selectionItem::selected, this, [=](){selectCanvas(newCanvas);});
        selectCanvas(newCanvas);
        connect(newCanvas, &MyCanvas::nameChanged, this, [=](QString text){
            m_pCanvasTitle->setText(text);
            m_pCanvasTitle->setMaximumWidth(QFontMetrics(QFont("Corbel Light", 24)).size(Qt::TextSingleLine, m_pCanvasTitle->text()).width() + 10);
            newLayer->setTitle(text);
        });
        connect(newCanvas, &MyCanvas::descChanged, this, [=](QString text){this->m_pCanvasDesc->setText(text);newLayer->setDescription(text);});
        connect(newCanvas, &MyCanvas::setDel, this, [=](MyCanvas *c){m_pCurSettingsPage->slideOut();deleteCanvas(c);layerSel->RemoveItem(newLayer);});
        m_pCreateNewPage->slideOut();
    });
    m_pCreateNewPage->AddContent(submit);
    m_pCreateNewPage->AddContent(dirSel);
    m_pCreateNewPage->AddContent(structureSel);
    m_pCreateNewPage->AddContent(whiteSpace);
    m_pCreateNewPage->AddContent(redescribe);
    m_pCreateNewPage->AddContent(rename);
//    m_pCreateNewPage->show();
//    m_pCreateNewPage->slideIn();
    //pageList.push_back(m_pCreateNewPage);
}

void MainWindow::initUi()
{
    createHeader();
    createHomePage();
    ui->displayLayout->addWidget(m_pTitleWidget);
    ui->displayLayout->addWidget(m_pHomePage);
    ui->displayLayout->setAlignment(Qt::AlignTop);
    return ;
}

void MainWindow::createHeader()
{
    QFont titleFont = QFont("Corbel Light", 24);
    QFontMetrics titleFm(titleFont);
    m_pCanvasTitle = new QLineEdit(this);
    m_pCanvasTitle->setFont(titleFont);
    m_pCanvasTitle->setText("START");
    m_pCanvasTitle->setMaxLength(20);
    m_pCanvasTitle->setReadOnly(true);
    m_pCanvasTitle->setMinimumHeight(titleFm.height());
    m_pCanvasTitle->setMaximumWidth(titleFm.size(Qt::TextSingleLine, "START").width() + 10);
    m_pCanvasTitle->setStyleSheet("background-color:#00000000;border-style:none;border-width:0px;margin-left:1px;");
    connect(m_pCanvasTitle, &QLineEdit::textEdited, m_pCanvasTitle, [=](QString text){m_pCanvasTitle->setMaximumWidth(titleFm.size(Qt::TextSingleLine, text).width());});

    QFont descFont = QFont("Corbel Light", 12);
    QFontMetrics descFm(descFont);
    m_pCanvasDesc = new QLineEdit(this);
    m_pCanvasDesc->setFont(descFont);
    m_pCanvasDesc->setText("Add your first canvas to start");
    m_pCanvasDesc->setMaxLength(128);
    m_pCanvasDesc->setReadOnly(true);
    m_pCanvasDesc->setMinimumHeight(descFm.lineSpacing());
    m_pCanvasDesc->setStyleSheet("background-color:#00000000;border-style:none;border-width:0px;");

    m_pSettingsIcon = new CustomIcon(":/icons/icons/settings.svg", "settings", 5, this);
    m_pSettingsIcon->setMinimumHeight(m_pCanvasTitle->height() * 0.7);
    m_pSettingsIcon->setMaximumWidth(m_pCanvasTitle->height() * 0.7);
    connect(m_pSettingsIcon, &CustomIcon::clicked, this, [=](){
        //旋转
        QPropertyAnimation *rotate = new QPropertyAnimation(m_pSettingsIcon, "rotationAngle", this);
        rotate->setDuration(750);
        rotate->setStartValue(0);
        rotate->setEndValue(90);
        rotate->setEasingCurve(QEasingCurve::InOutExpo);
        rotate->start();
        m_pCurSettingsPage->slideIn();
    });
    m_pLayersIcon = new CustomIcon(":/icons/icons/layers.svg", "layers", 5, this);
    m_pLayersIcon->setMinimumHeight(m_pCanvasTitle->height() * 0.7);
    m_pLayersIcon->setMaximumWidth(m_pCanvasTitle->height() * 0.7);
    connect(m_pLayersIcon, &CustomIcon::clicked, this, [=](){
        m_pLayersPage->slideIn();
    });

    //创建关于按钮
    m_pAboutIcon = new CustomIcon(":/icons/icons/about.svg", "about", 5, this);
    m_pAboutIcon->setMinimumHeight(m_pCanvasTitle->height() * 0.7);
    m_pAboutIcon->setMaximumWidth(m_pCanvasTitle->height() * 0.7);
    connect(m_pAboutIcon, &CustomIcon::clicked, this, [=](){
        m_pSlideAbout->slideIn();
    });

    QHBoxLayout *innerLayout = new QHBoxLayout();
    innerLayout->setContentsMargins(0, 0, 0, 0);
    innerLayout->setSpacing(10);
    innerLayout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    innerLayout->addWidget(m_pCanvasTitle);
    innerLayout->addWidget(m_pSettingsIcon);
    innerLayout->addWidget(m_pLayersIcon);
    innerLayout->addWidget(m_pAboutIcon);

    m_pTitleWidget = new QWidget(this);
    m_pTitleWidget->setMaximumHeight(m_pCanvasTitle->height() + m_pCanvasDesc->height());
    QVBoxLayout *outerLayout = new QVBoxLayout(m_pTitleWidget);
    m_pTitleWidget->setLayout(outerLayout);
    outerLayout->setContentsMargins(0, 0, 0, 0);
    outerLayout->setSpacing(0);

    outerLayout->addLayout(innerLayout);
    outerLayout->addWidget(m_pCanvasDesc);
}

void MainWindow::createHomePage()
{
    m_pHomePage = new QWidget(this);
    m_pHomePage->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    BigIconButton *createNew = new BigIconButton(":/icons/icons/create.png", "Create new", 10, this);
    connect(createNew, &BigIconButton::signalClicked, m_pCreateNewPage, [=](){rename->setValue("Layer_" + QString::asprintf("%d", canvasList.size()));/*redescribe->setValue("No description");*/m_pCreateNewPage->slideIn();});
//    connect(createNew, SIGNAL(signalClicked()), this, SLOT(slotCreateNewPage()));
    createNew->setScale(0.9);
    BigIconButton *openFile = new BigIconButton(":/icons/icons/open.png", "Open from file", 10, this);
    connect(openFile, &BigIconButton::signalClicked, this, [=](){
        QString inputPath = QFileDialog::getOpenFileName(this, tr("Open map"), " ",  tr("Map File(*.map)"));
        if(!inputPath.isEmpty()){
            MyCanvas *newCanvas = loadCanvas(inputPath);
            if(newCanvas != nullptr){
                canvasList.push_back(newCanvas);
                selectionItem *newLayer = new selectionItem(newCanvas->name(), newCanvas->description(), m_pLayersPage);
                layerSel->AddItem(newLayer);
                layerSel->SetSelection(newLayer);
//                pageList.push_back(newCanvas->settingPage());
                connect(newLayer, &selectionItem::selected, this, [=](){selectCanvas(newCanvas);});
                selectCanvas(newCanvas);
                connect(newCanvas, &MyCanvas::nameChanged, this, [=](QString text){
                    m_pCanvasTitle->setText(text);
                    m_pCanvasTitle->setMaximumWidth(QFontMetrics(QFont("Corbel Light", 24)).size(Qt::TextSingleLine, m_pCanvasTitle->text()).width() + 10);
                    newLayer->setTitle(text);
                });
                connect(newCanvas, &MyCanvas::descChanged, this, [=](QString text){this->m_pCanvasDesc->setText(text);newLayer->setDescription(text);});
                connect(newCanvas, &MyCanvas::setDel, this, [=](MyCanvas *c){m_pCurSettingsPage->slideOut();deleteCanvas(c);layerSel->RemoveItem(newLayer);});
                m_pCreateNewPage->slideOut();
            }
        }
    });
    QHBoxLayout *defaultPageLayout = new QHBoxLayout(m_pHomePage);
    m_pHomePage->setLayout(defaultPageLayout);
    defaultPageLayout->setContentsMargins(50, 30, 50, 80);
    defaultPageLayout->setSpacing(20);
    defaultPageLayout->addWidget(createNew);
    defaultPageLayout->addWidget(openFile);
}

MyCanvas* MainWindow::loadCanvas(const QString &path){
    QFile input(path);
    input.open(QIODevice::ReadOnly);
    QTextStream ts(&input);
    QString magicString = ts.readLine();
    if(magicString != "VFdGeWFXUnZaekl3TURJd05ESTE=")   return nullptr;
    MyCanvas *newCanvas = new MyCanvas(ts, cornerRadius, this);
    input.close();
    return newCanvas;
}
